package com.zshan.clinic.admin.service.stat;

import com.zshan.clinic.admin.entity.vo.StatClinicIncomeDailyVo;
import com.zshan.clinic.admin.mapper.stat.SpecStatMapper;
import com.zshan.clinic.common.exception.BusinessFailException;
import com.zshan.clinic.common.util.page.PageInfo;
import com.zshan.clinic.common.util.page.PageUtils;
import com.zshan.clinic.common.util.string.StringUtil;
import com.zshan.clinic.database.dao.StatClinicIncomeDailyMapper;
import com.zshan.clinic.database.model.StatClinicIncomeDaily;
import com.zshan.clinic.database.model.StatClinicIncomeDailyExample;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;

/**
 * 诊所营收概况
 * @author lichen
 */
@Service
@Slf4j
public class ClinicIncomeDailyService {

    @Autowired
    private StatClinicIncomeDailyMapper statClinicIncomeDailyMapper;

    @Autowired
    private SpecStatMapper specStatMapper;

    /**
     * 获取诊所营收概况
     * @param clinicId 诊所ID
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @return
     */
    public StatClinicIncomeDailyVo getClinicIncome(Long clinicId,LocalDate startDate,LocalDate endDate){
        //查询诊所营收概况
        return specStatMapper.getClinicIncome(clinicId,startDate,endDate);
    }




    /**
     * 保存诊所营收统计
     * @param statClinicIncomeDaily
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(StatClinicIncomeDaily statClinicIncomeDaily) {
        statClinicIncomeDaily.setStatDate(LocalDate.now());
        // 先按 clinicId + statDate 查询当天是否已有记录
        StatClinicIncomeDaily dbStatClinicIncomeDaily = getStatClinicIncomeById(
                statClinicIncomeDaily.getClinicId(), statClinicIncomeDaily.getStatDate());
        if (dbStatClinicIncomeDaily == null) {
            // 初始化空值为 0，避免 null
            if (statClinicIncomeDaily.getIncomeAmount() == null) {
                statClinicIncomeDaily.setIncomeAmount(0);
            }
            if (statClinicIncomeDaily.getIncomeCount() == null) {
                statClinicIncomeDaily.setIncomeCount(0);
            }
            if (statClinicIncomeDaily.getRegCount() == null) {
                statClinicIncomeDaily.setRegCount(0);
            }
            if (statClinicIncomeDaily.getMedicalCount() == null) {
                statClinicIncomeDaily.setMedicalCount(0);
            }
            if (statClinicIncomeDaily.getFollowupCount() == null) {
                statClinicIncomeDaily.setFollowupCount(0);
            }
            if (statClinicIncomeDaily.getExamCount() == null) {
                statClinicIncomeDaily.setExamCount(0);
            }
            if (statClinicIncomeDaily.getLabCount() == null) {
                statClinicIncomeDaily.setLabCount(0);
            }
            if (statClinicIncomeDaily.getDispenseCount() == null) {
                statClinicIncomeDaily.setDispenseCount(0);
            }
            if (statClinicIncomeDaily.getDeliveryCount() == null) {
                statClinicIncomeDaily.setDeliveryCount(0);
            }
            if (statClinicIncomeDaily.getExecCount() == null) {
                statClinicIncomeDaily.setExecCount(0);
            }

            statClinicIncomeDaily.setCreateTime(new Date());
            statClinicIncomeDailyMapper.insertSelective(statClinicIncomeDaily);
        } else {
            // 累加各类统计字段
            if (statClinicIncomeDaily.getIncomeAmount() != null) {
                dbStatClinicIncomeDaily.setIncomeAmount(
                        dbStatClinicIncomeDaily.getIncomeAmount() + statClinicIncomeDaily.getIncomeAmount());
            }
            if (statClinicIncomeDaily.getIncomeCount() != null) {
                dbStatClinicIncomeDaily.setIncomeCount(
                        dbStatClinicIncomeDaily.getIncomeCount() + statClinicIncomeDaily.getIncomeCount());
            }
            if (statClinicIncomeDaily.getRegCount() != null) {
                dbStatClinicIncomeDaily.setRegCount(
                        dbStatClinicIncomeDaily.getRegCount() + statClinicIncomeDaily.getRegCount());
            }
            if (statClinicIncomeDaily.getMedicalCount() != null) {
                dbStatClinicIncomeDaily.setMedicalCount(
                        dbStatClinicIncomeDaily.getMedicalCount() + statClinicIncomeDaily.getMedicalCount());
            }
            if (statClinicIncomeDaily.getFollowupCount() != null) {
                dbStatClinicIncomeDaily.setFollowupCount(
                        dbStatClinicIncomeDaily.getFollowupCount() + statClinicIncomeDaily.getFollowupCount());
            }
            if (statClinicIncomeDaily.getExamCount() != null) {
                dbStatClinicIncomeDaily.setExamCount(
                        dbStatClinicIncomeDaily.getExamCount() + statClinicIncomeDaily.getExamCount());
            }
            if (statClinicIncomeDaily.getLabCount() != null) {
                dbStatClinicIncomeDaily.setLabCount(
                        dbStatClinicIncomeDaily.getLabCount() + statClinicIncomeDaily.getLabCount());
            }
            if (statClinicIncomeDaily.getDispenseCount() != null) {
                dbStatClinicIncomeDaily.setDispenseCount(
                        dbStatClinicIncomeDaily.getDispenseCount() + statClinicIncomeDaily.getDispenseCount());
            }
            if (statClinicIncomeDaily.getDeliveryCount() != null) {
                dbStatClinicIncomeDaily.setDeliveryCount(
                        dbStatClinicIncomeDaily.getDeliveryCount() + statClinicIncomeDaily.getDeliveryCount());
            }
            if (statClinicIncomeDaily.getExecCount() != null) {
                dbStatClinicIncomeDaily.setExecCount(
                        dbStatClinicIncomeDaily.getExecCount() + statClinicIncomeDaily.getExecCount());
            }

            dbStatClinicIncomeDaily.setUpdateTime(new Date());
            statClinicIncomeDailyMapper.updateByPrimaryKeySelective(dbStatClinicIncomeDaily);
        }
    }


    public StatClinicIncomeDaily getStatClinicIncomeById(Long clinicId, LocalDate statDate) {
        StatClinicIncomeDailyExample example = new StatClinicIncomeDailyExample();
        StatClinicIncomeDailyExample.Criteria criteria = example.createCriteria();
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andStatDateEqualTo(statDate);
        List<StatClinicIncomeDaily> dailyList = statClinicIncomeDailyMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(dailyList)){
            return null;
        }
        return dailyList.get(0);
    }

    /**
     * 分页查询诊所营收概况
     * @param clinicId 诊所ID（可选条件）
     * @param pageNo 页码
     * @param pageSize 每页条数
     * @return 分页结果
     */
    public PageInfo<StatClinicIncomeDaily> getClinicIncomeListByCondition(Long clinicId, Integer pageNo, Integer pageSize) {
        StatClinicIncomeDailyExample example = new StatClinicIncomeDailyExample();
        StatClinicIncomeDailyExample.Criteria criteria = example.createCriteria();
        if (!StringUtil.isBlank(clinicId)) {
            criteria.andClinicIdEqualTo(clinicId);
        }
        Long totalCount = statClinicIncomeDailyMapper.countByExample(example);
        if (totalCount == null || totalCount == 0) {
            return PageInfo.build();
        }
        example.setOffset(PageUtils.getOffset(pageNo, pageSize));
        example.setLimit(pageSize);
        example.setOrderByClause("stat_date desc");
        List<StatClinicIncomeDaily> list = statClinicIncomeDailyMapper.selectByExample(example);
        return new PageInfo<>(totalCount, list);
    }

    /**
     * 添加诊所营收概况
     * @param statClinicIncomeDaily 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void addClinicIncome(StatClinicIncomeDaily statClinicIncomeDaily) {
        validateClinicIncome(statClinicIncomeDaily);
        statClinicIncomeDaily.setCreateTime(new Date());
        statClinicIncomeDailyMapper.insertSelective(statClinicIncomeDaily);
    }

    /**
     * 校验诊所营收概况参数
     * @param statClinicIncomeDaily 实体
     */
    public void validateClinicIncome(StatClinicIncomeDaily statClinicIncomeDaily) {
        // TODO: 补充业务校验逻辑
    }

    /**
     * 根据ID查询诊所营收概况
     * @param id 主键
     * @return 诊所营收概况记录
     */
    public StatClinicIncomeDaily getClinicIncomeById(Long id) {
        if (id == null) {
            return null;
        }
        return statClinicIncomeDailyMapper.selectByPrimaryKey(id);
    }

    /**
     * 修改诊所营收概况
     * @param statClinicIncomeDaily 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateClinicIncome(StatClinicIncomeDaily statClinicIncomeDaily) {
        validateClinicIncome(statClinicIncomeDaily);
        StatClinicIncomeDaily dbClinicIncome = getClinicIncomeById(statClinicIncomeDaily.getId());
        if (dbClinicIncome == null) {
            throw new BusinessFailException("诊所营收记录不存在");
        }
        statClinicIncomeDaily.setUpdateTime(new Date());
        statClinicIncomeDailyMapper.updateByPrimaryKeySelective(statClinicIncomeDaily);
    }

    /**
     * 删除诊所营收概况（逻辑删除）
     * @param statClinicIncomeDaily 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteClinicIncome(StatClinicIncomeDaily statClinicIncomeDaily) {
        StatClinicIncomeDaily dbClinicIncome = getClinicIncomeById(statClinicIncomeDaily.getId());
        if (dbClinicIncome == null) {
            throw new BusinessFailException("诊所营收记录不存在");
        }
        statClinicIncomeDailyMapper.deleteByPrimaryKey(dbClinicIncome.getId());
    }
}
